﻿Imports System.Runtime.CompilerServices
Imports System.Text.RegularExpressions

''' <summary>
''' 型拡張メソッド
''' </summary>
''' <remarks></remarks>
Public Module TypeExtension
    ''' <summary>
    ''' エンティティ定義に変換します
    ''' </summary>
    ''' <param name="source"></param>
    ''' <returns></returns>
    ''' <remarks>キャッシュしています</remarks>
    <Extension()>
    Public Function ToEntityDefinition(source As Type) As EntityDefinition
        Static caches As New Dictionary(Of Type, EntityDefinition)

        If caches.ContainsKey(source) Then Return caches(source)

        Dim c = EntityDefinition.Create(source)

        '自己参照があるとClassDefinitionインスタンス時にコールされることがあり、
        '既に登録されているケースがある
        If caches.ContainsKey(source) Then
            Return caches(source)
        Else
            caches.Add(source, c)
            Return c
        End If
    End Function

    ''' <summary>
    ''' Nリレーションキー命名規約にあっているかを示します
    ''' </summary>
    ''' <param name="source"></param>
    ''' <returns></returns>
    ''' <remarks>KeyConstraintを参照しています</remarks>
    <Extension()>
    Public Function IsNRelation(source As Type) As Boolean
        If source Is Nothing Then Throw New ArgumentNullException("source")

        'Nリレーション判定
        Dim m As Match = Regex.Match(source.Name, KeyConstraint.Instance.NRelationClassPattern)

        'クラス名が命名規約とは異なる
        If m.Success = False Then Return False

        Dim names As String() = {m.Groups("parent1").Value, m.Groups("parent2").Value}

        '命名規約にあったプロパティが存在しない場合
        If (From el In names Where source.GetProperty(el) Is Nothing).Any Then Return False

        'Nリレーションとする
        Return True
    End Function
End Module
